home *** CD-ROM | disk | FTP | other *** search
/ Oh!X 2000 Spring / Oh!X 2000 Spring Special CD-ROM (Japan) (Part 1).7z / Oh!X 2000 Spring Special CD-ROM (Japan) (Part 1).bin / MIPSSIM / dis.c < prev    next >
C/C++ Source or Header  |  1999-12-02  |  54KB  |  1,871 lines

  1. #include <stdio.h>
  2. #include "define.h"
  3. #define BigEndian     0
  4. #define LittleEndian  1
  5. #define MIPS1         0
  6. #define MIPS3         1
  7. #define MIPS16        2
  8. #define MIPS4         3
  9. static char  insn_buf[256];
  10. static int   ty_mips   = MIPS4;
  11. static int   endian = LittleEndian;
  12. static ulong saddr  = 0;
  13. static ulong opcode;
  14.  
  15. static void dis_init(void);
  16. static void dis_cp1(int,int,int,int,int,ulong);
  17. static void dis_special(int,int,int,int,int,int,ulong,ulong);
  18. static void dis_bcond(int,int,int,int,int,int,ulong,ulong);
  19. static void dis_copz(int,int,int,int,int,int,int,ulong,ulong);
  20. static void dis_cop1x(int,int,int,int,int,int,ulong,ulong);
  21. static void dis_cache(int,int,int,long,ulong);
  22. static void dis_mips(ulong,ulong);
  23. static int  mips16_reg_get(int);
  24. static void dis_mips16_RR(ulong,ulong,ulong,ulong,ulong);
  25. static void dis_mips16_extend(ulong,ulong);
  26. static void dis_mips16(ulong,ulong);
  27.  
  28. void dis_one(ulong hi, ulong lo)
  29. {
  30.   int err;
  31.   opcode = get_icache(hi, lo, &err);
  32.   dis_mips(opcode, lo);
  33. }
  34.  
  35. void dis16_one(ulong hi, ulong lo)
  36. {
  37.   int err;
  38.   opcode = get_icache(hi,lo,&err);
  39.   if(lo&3)
  40.     opcode = (opcode>>16)&0xffff;
  41.   else
  42.     opcode = opcode&0xffff;
  43.   dis_mips16(opcode, lo);
  44. }
  45.  
  46. void dismips(char *base, char *num)
  47. {
  48.   int cnt;
  49.  
  50.   if(*base!='\0')
  51.     saddr = (ulong)gen_val(base);
  52.   if(*num=='\0')
  53.     cnt = 20;
  54.   else
  55.     cnt = (int)gen_val(num);
  56.   dis_init();
  57.   do{
  58.     dis_one(sign_extend(saddr), saddr);
  59.     saddr += 4;
  60.   }while(--cnt);
  61. }
  62.  
  63. void dismips16(char *base, char *num)
  64. {
  65.   int cnt;
  66.  
  67.   if(*base!='\0')
  68.     saddr = (ulong)gen_val(base);
  69.   if(*num=='\0')
  70.     cnt = 20;
  71.   else
  72.     cnt = (int)gen_val(num);
  73.   dis_init();
  74.   do{
  75.     dis16_one(sign_extend(saddr),saddr);
  76.     saddr += 2;
  77.   }while(--cnt);
  78. }
  79.  
  80.  
  81.  
  82. /*********************************************************************/
  83. static char *regn_1[]={
  84. "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
  85. "r8", "r9", "r10","r11","r12","r13","r14","r15",
  86. "r16","r17","r18","r19","r20","r21","r22","r23",
  87. "r24","r25","r26","r27","r28","r29","r30","r31"
  88. };
  89.  
  90. static char *regn_2[]={
  91. "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
  92. "$8", "$9", "$10","$11","$12","$13","$14","$15",
  93. "$16","$17","$18","$19","$20","$21","$22","$23",
  94. "$24","$25","$26","$27","$28","$29","$30","$31"
  95. };
  96.  
  97. static char *cregn_1[]={
  98. "C0_Index",     "C0_Random",    "C0_EntryLo",   "cp0reg03",
  99. "C0_Context",   "cp0reg5",      "cp0reg6",      "cp0reg7",
  100. "C0_BadVAddr",  "cp0reg9",      "C0_EntryHi",   "cp0reg11",
  101. "C0_SR",        "C0_Cause",     "C0_EPC",       "C0_Prid",
  102. "cp0reg16",     "cp0reg17",     "cp0reg18",     "cp0reg19",
  103. "cp0reg20",     "cp0reg21",     "cp0reg22",     "cp0reg23",
  104. "cp0reg24",     "cp0reg25",     "cp0reg26",     "cp0reg27",
  105. "cp0reg28",     "cp0reg29",     "cp0reg30",     "cp0reg31"
  106. };
  107.  
  108. static char *cregn_2[]={
  109. "C0_Index",     "C0_Random",    "C0_EntryLo0",  "C0_EntryLo1",
  110. "C0_Context",   "C0_PageMask",  "C0_Wired",     "cp0reg7",
  111. "C0_BadVAddr",  "C0_Count",     "C0_EntryHi",   "C0_Compare",
  112. "C0_SR",        "C0_Cause",     "C0_EPC",       "C0_Prid",
  113. "C0_Config",    "C0_LLAddr",    "C0_WatchLo",   "C0_WatchHi",
  114. "C0_XContext",  "cp0reg21",     "cp0reg22",     "cp0reg23",
  115. "cp0reg24",     "cp0reg25",     "C0_ECC",       "C0_CacheErr",
  116. "C0_TagLo",     "C0_TagHi",     "C0_ErrorEPC",  "cp0reg31",
  117. };
  118.  
  119. char **regn =regn_1;
  120. char **cregn=cregn_2;
  121.  
  122. static char    *jnam[] ={"j","jal"};
  123. static char    *bnam[] ={"beq","bne","blez","bgtz"};
  124. static char    *inam[] ={"addi","addiu","slti","sltiu","andi","ori","xori"};
  125. static char    *lsnam[]={"lb","lh","lwl","lw","lbu","lhu","lwr","lwu","sb","sh","swl","sw","sdl","sdr","swr"};
  126. static char    *snum[] ={"sll","","srl","sra","sllv","","srlv","srav"};
  127. static char    *mdnam[]={"mult","multu","div","divu"};
  128. static char    *anam[] ={"add","addu","sub","subu","and","or","xor","nor","","","slt","sltu"};
  129. static char    *tnam[] ={"tge","tgeu","tlt","tltu","teq","","tne",""};
  130. static char    *fnam[]={
  131. "add",  "sub",  "mul",  "div",  "sqrt",     "abs",  "mov",  "neg",
  132. "round.l","trunc.l","ceil.l","floor.l","round.w","trunc.w","ceil.w","floor.w",
  133. "",     "movt", "movz", "movn",  "",    "recip",    "rsqrt", "",
  134. "",     "",     "",     "",     "",     "",     "",     "",
  135. "cvt.s","cvt.d","",     "",     "cvt.w","cvt.l","",     "",
  136. "",     "",     "",     "",     "",     "",     "",     "",
  137. "c.f",  "c.un", "c.eq", "c.ueq","c.olt","c.ult","c.ole","c.ule",
  138. "c.sf", "c.ngle","c.seq","c.ngl","c.lt","c.nge","c.le", "c.ngt"
  139. };
  140.  
  141. static char *macc_nam[]={"madd","msub","nmadd","nmsub"};
  142.  
  143. static char *pref_hint[]={
  144. "load",
  145. "store",
  146. "",
  147. "",
  148. "load_streamed",
  149. "store_streamed",
  150. "load_retained",
  151. "store_retained",
  152. "","","","","","","","","","","","","","","","","",
  153. "writeback_invalidate"
  154. };
  155.  
  156. static void dis_init(void)
  157. {
  158.   regn = regn_1;
  159.   if(ty_mips==MIPS1)
  160.     cregn = cregn_1;
  161.   else
  162.     cregn = cregn_2;
  163.   if(ty_mips==MIPS16)
  164.     saddr &= 0xfffffffe;
  165.   else
  166.     saddr &= 0xfffffffc;
  167. }
  168.  
  169. static void dis_cp1(int fmt,int ft,int fs,int fd,int func,ulong pc)
  170. {
  171.   ulong temppc;
  172.   int   immd;
  173.   immd = (fs<<11)|(fd<<6)|func;
  174.   if(immd&0x8000){
  175.     immd |=0xffff0000;
  176.     temppc=(immd<<2);
  177.   }
  178.   else temppc=immd<<2;
  179.   temppc=(pc+4)+temppc;
  180.   if((fnam[func&0x3f][0])&&(fmt&0x10)){
  181.     switch(func&0x38){
  182.     case 000: /* operation */
  183.       if((func&7)<4){
  184.     sprintf(insn_buf,"%s.%c\tfp%d,fp%d,fp%d\n",
  185.         fnam[func],(fmt&1)? 'd':'s',fd&0x1f,fs&0x1f,ft&0x1f);
  186.       }
  187.       else{
  188.     sprintf(insn_buf,"%s.%c\tfp%d,fp%d\n",
  189.         fnam[func],(fmt&1)? 'd':'s',fd&0x1f,fs&0x1f);
  190.       }
  191.       break;
  192.     case 020:
  193.       if((func&7)<2)
  194.     sprintf(insn_buf,"%s.%c\tfp%d,fp%d,cc%d\n",
  195.         (ft&1)? "movt" : "movf",
  196.         (fmt&1)? 'd':'s',
  197.         fd&0x1f,fs&0x1f,(ft>>2)&7);
  198.       else if((func&7)<4)
  199.     sprintf(insn_buf,"%s.%c\tfp%d,fp%d,%s\n",
  200.         fnam[func],(fmt&1)? 'd':'s',fd&0x1f,fs&0x1f,regn[ft&0x1f]);
  201.       else
  202.     sprintf(insn_buf,"%s.%c\tfp%d,fp%d\n",
  203.         fnam[func],(fmt&1)? 'd':'s',fd&0x1f,fs&0x1f);
  204.       break;
  205.     case 010: /* convert to integer */
  206.     case 040: /* convert */
  207.       sprintf(insn_buf,"%s.%c\tfp%d,fp%d\n",
  208.           fnam[func],(fmt&1)? ((fmt&4)?'l':'d')
  209.           : ((fmt&4)?'w':'s'),fd&0x1f,fs&0x1f);
  210.       break;
  211.     case 060: /* c */
  212.     case 070:
  213.       if(ty_mips==MIPS4)
  214.     sprintf(insn_buf,"%s.%c\tcc%d,fp%d,fp%d\n",
  215.         fnam[func],(fmt&1)? 'd':'s',(fd>>2)&7,fs&0x1f,ft&0x1f);
  216.       else
  217.     sprintf(insn_buf,"%s.%c\tfp%d,fp%d\n",
  218.         fnam[func],(fmt&1)? 'd':'s',fs&0x1f,ft&0x1f);
  219.       break;
  220.     }
  221.   }
  222.   else{
  223.     switch(fmt&0xf){
  224.     case 000:/* MF */
  225.       sprintf(insn_buf,"mfc1\t%s,fp%d\n",regn[ft],fs&0x1f);
  226.       break;
  227.     case 001:/* DMF */
  228.       sprintf(insn_buf,"dmfc1\t%s,fp%d\n",regn[ft],fs&0x1f);
  229.       break;
  230.     case 002:/* CF */
  231.       if((fs&0x1f)==31)
  232.     sprintf(insn_buf,"cfc1\t%s,C1_SR\n",regn[ft]);
  233.       else
  234.     sprintf(insn_buf,"cfc1\t%s,C1_Reg%d\n",regn[ft],fs&0x1f);
  235.       break;
  236.     case 004:/* MT */
  237.       sprintf(insn_buf,"mtc1\t%s,fp%d\n",regn[ft],fs&0x1f);
  238.       break;
  239.     case 005:/* DMT */
  240.       sprintf(insn_buf,"dmtc1\t%s,fp%d\n",regn[ft],fs&0x1f);
  241.       break;
  242.     case 006:/* CT */
  243.       if((fs&0x1f)==31)
  244.     sprintf(insn_buf,"ctc1\t%s,C1_SR\n",regn[ft]);
  245.       else
  246.     sprintf(insn_buf,"ctc1\t%s,C1_Reg%d\n",regn[ft],fs&0x1f);
  247.       break;
  248.     case 010:/* BC */
  249.       if((ft&3)==0){
  250.     if(ty_mips==MIPS4)
  251.       sprintf(insn_buf,"bc1f\tcc%d,0x%08x\n",(ft>>2)&7,(long)temppc);
  252.     else
  253.       sprintf(insn_buf,"bc1f\t0x%08x\n",(long)temppc);
  254.       }
  255.       else if((ft&3)==1){
  256.     if(ty_mips==MIPS4)
  257.       sprintf(insn_buf,"bc1t\tcc%d,0x%08x\n",(ft>>2)&7,(long)temppc);
  258.     else
  259.       sprintf(insn_buf,"bc1t\t0x%08x\n",(long)temppc);
  260.       }
  261.       else if((ft&3)==2){
  262.     if(ty_mips==MIPS4)
  263.       sprintf(insn_buf,"bc1fl\tcc%d,0x%08x\n",(ft>>2)&7,(long)temppc);
  264.     else
  265.       sprintf(insn_buf,"bc1fl\t0x%08x\n",(long)temppc);
  266.       }
  267.       else if((ft&3)==3){
  268.     if(ty_mips==MIPS4)
  269.       sprintf(insn_buf,"bc1tl\tcc%d,0x%08x\n",(ft>>2)&7,(long)temppc);
  270.     else
  271.       sprintf(insn_buf,"bc1tl\t0x%08x\n",(long)temppc);
  272.       }
  273.       else
  274.     sprintf(insn_buf,".word\t0x%08x\n",(long)opcode);
  275.       break;
  276.     default:
  277.       sprintf(insn_buf,".word\t0x%08x\n",(long)opcode);
  278.     }
  279.   }
  280. }
  281.  
  282. static void dis_special(int rs,int rt,int rd,int sa,int func,int immd,ulong targ,ulong pc)
  283. {
  284.   switch(func){
  285.   case 000:/* SLL */
  286.   case 002:/* SRL */
  287.   case 003:/* SRA */
  288.     sprintf(insn_buf,"%s\t%s,%s,%d\n",snum[func],regn[rd],regn[rt],sa);
  289.     break;
  290.   case 001:/* MOVT/MOVF */
  291.     sprintf(insn_buf,"%s\t%s,%s,cc%d\n",
  292.         (rt&1)? "movt" : "movf",
  293.         regn[rd],regn[rs],(rt>>2)&7);
  294.     break;
  295.   case 004:/* SLLV */
  296.   case 006:/* SRLV */
  297.   case 007:/* SRAV */
  298.     sprintf(insn_buf,"%s\t%s,%s,%s\n",snum[func],regn[rd],regn[rt],regn[rs]);
  299.     break;
  300.   case 010:/* JR */
  301.     sprintf(insn_buf,"jr\t%s\n",regn[rs]);
  302.     break;
  303.   case 011:/* JALR */
  304.     sprintf(insn_buf,"jalr\t%s,%s\n",regn[rd],regn[rs]);
  305.     break;
  306.   case 012:/* MOVZ */
  307.   case 013:/* MOVN */
  308.     sprintf(insn_buf,"%s\t%s,%s,%s\n",
  309.         (func==012)? "movz" : "movn",
  310.         regn[rd],regn[rs],regn[rt]);
  311.     break;
  312.   case 014:/* SYSCALL */
  313.     sprintf(insn_buf,"syscall\t%d\n",(rs<<15)|(rt<<10)|(rd<<5)|sa);
  314.     break;
  315.   case 015:/* BREAK */
  316.     sprintf(insn_buf,"break\t%d\n",(rs<<15)|(rt<<10)|(rd<<5)|sa);
  317.     break;
  318.   case 017:
  319.     sprintf(insn_buf,"sync\n");
  320.     break;
  321.   case 020:/* MFHI */
  322.     sprintf(insn_buf,"mfhi\t%s\n",regn[rd]);
  323.     break;
  324.   case 021:/* MTHI */
  325.     sprintf(insn_buf,"mthi\t%s\n",regn[rs]);
  326.     break;
  327.   case 022:/* MFLO */
  328.     sprintf(insn_buf,"mflo\t%s\n",regn[rd]);
  329.     break;
  330.   case 023:/* MTLO */
  331.     sprintf(insn_buf,"mtlo\t%s\n",regn[rs]);
  332.     break;
  333.   case 024:/* DSLLV */
  334.   case 026:/* DSRLV */
  335.   case 027:/* DSRAV */
  336.     sprintf(insn_buf,"d%s\t%s,%s,%s\n",snum[func-020],regn[rd],regn[rt],regn[rs]);
  337.     break;
  338.   case 030:/* MULT */
  339.   case 031:/* MULTU */
  340.   case 032:/* DIV */
  341.   case 033:/* DIVU */
  342.     sprintf(insn_buf,"%s\t%s,%s\n",mdnam[func-030],regn[rs],regn[rt]);
  343.     break;
  344.   case 034:/* DMULT */
  345.   case 035:/* DMULTU */
  346.   case 036:/* DDIV */
  347.   case 037:/* DDIVU */
  348.     sprintf(insn_buf,"d%s\t%s,%s\n",mdnam[func-034],regn[rs],regn[rt]);
  349.     break;
  350.   case 040:/* ADD */
  351.   case 041:/* ADDU */
  352.   case 042:/* SUB */
  353.   case 043:/* SUBU */
  354.   case 044:/* AND */
  355.   case 045:/* OR */
  356.   case 046:/* XOR */
  357.   case 047:/* NOR */
  358.   case 052:/* SLT */
  359.   case 053:/* SLTU */
  360.     sprintf(insn_buf,"%s\t%s,%s,%s\n",anam[func-040],regn[rd],regn[rs],regn[rt]);
  361.     break;
  362.   case 054:/* DADD */
  363.   case 055:/* DADDU */
  364.   case 056:/* DSUB */
  365.   case 057:/* DSUBU */
  366.     sprintf(insn_buf,"d%s\t%s,%s,%s\n",anam[func-054],regn[rd],regn[rs],regn[rt]);
  367.     break;
  368.   case 060:/* TGE */
  369.   case 061:/* TGEU */
  370.   case 062:/* TLT */
  371.   case 063:/* TLTU */
  372.   case 064:/* TEQ */
  373.   case 066:/* TNE */
  374.     sprintf(insn_buf,"%s\t%s,%s\n",tnam[func-060],regn[rs],regn[rt]);
  375.     break;
  376.   case 070:/* DSLL */
  377.   case 072:/* DSRL */
  378.   case 073:/* DSRA */
  379.     sprintf(insn_buf,"d%s\t%s,%s,%d\n",snum[func-070],regn[rd],regn[rt],sa);
  380.     break;
  381.   case 074:/* DSLL32 */
  382.   case 076:/* DSRL32 */
  383.   case 077:/* DSRA32 */
  384.     sprintf(insn_buf,"d%s32\t%s,%s,%d\n",snum[func-074],regn[rd],regn[rt],sa);
  385.     break;
  386.   case 050:/* MACC */
  387.     switch(sa){
  388.     case 0x00:
  389.       sprintf(insn_buf,"macc\t%s,%s,%s\n",regn[rd],regn[rs],regn[rt]);
  390.       break;
  391.     case 0x01:
  392.       sprintf(insn_buf,"maccu\t%s,%s,%s\n",regn[rd],regn[rs],regn[rt]);
  393.       break;
  394.     case 0x08:
  395.       sprintf(insn_buf,"macch\t%s,%s,%s\n",regn[rd],regn[rs],regn[rt]);
  396.       break;
  397.     case 0x09:
  398.       sprintf(insn_buf,"macchu\t%s,%s,%s\n",regn[rd],regn[rs],regn[rt]);
  399.       break;
  400.     case 0x10:
  401.       sprintf(insn_buf,"maccs\t%s,%s,%s\n",regn[rd],regn[rs],regn[rt]);
  402.       break;
  403.     case 0x11:
  404.       sprintf(insn_buf,"maccus\t%s,%s,%s\n",regn[rd],regn[rs],regn[rt]);
  405.       break;
  406.     case 0x18:
  407.       sprintf(insn_buf,"macchs\t%s,%s,%s\n",regn[rd],regn[rs],regn[rt]);
  408.       break;
  409.     case 0x19:
  410.       sprintf(insn_buf,"macchus\t%s,%s,%s\n",regn[rd],regn[rs],regn[rt]);
  411.       break;
  412.     default:
  413.       sprintf(insn_buf,".word\t0x%08x\n",opcode);
  414.     }
  415.     break;
  416.   case 051:/* DMACC */
  417.     switch(sa){
  418.     case 0x00:
  419.       sprintf(insn_buf,"dmacc\t%s,%s,%s\n",regn[rd],regn[rs],regn[rt]);
  420.       break;
  421.     case 0x01:
  422.       sprintf(insn_buf,"dmaccu\t%s,%s,%s\n",regn[rd],regn[rs],regn[rt]);
  423.       break;
  424.     case 0x08:
  425.       sprintf(insn_buf,"dmacch\t%s,%s,%s\n",regn[rd],regn[rs],regn[rt]);
  426.       break;
  427.     case 0x09:
  428.       sprintf(insn_buf,"dmacchu\t%s,%s,%s\n",regn[rd],regn[rs],regn[rt]);
  429.       break;
  430.     case 0x10:
  431.       sprintf(insn_buf,"dmaccs\t%s,%s,%s\n",regn[rd],regn[rs],regn[rt]);
  432.       break;
  433.     case 0x11:
  434.       sprintf(insn_buf,"dmaccus\t%s,%s,%s\n",regn[rd],regn[rs],regn[rt]);
  435.       break;
  436.     case 0x18:
  437.       sprintf(insn_buf,"dmacchs\t%s,%s,%s\n",regn[rd],regn[rs],regn[rt]);
  438.       break;
  439.     case 0x19:
  440.       sprintf(insn_buf,"dmacchus\t%s,%s,%s\n",regn[rd],regn[rs],regn[rt]);
  441.       break;
  442.     default:
  443.       sprintf(insn_buf,".word\t0x%08x\n",opcode);
  444.     }
  445.     break;
  446.   default:
  447.     sprintf(insn_buf,".word\t0x%08x\n",opcode);
  448.   }
  449. }
  450.  
  451. static void dis_bcond(int rs,int rt,int rd,int sa,int func,int immd,ulong targ,ulong pc)
  452. {
  453.   ulong temppc;
  454.   if(immd&0x8000){
  455.     immd |=0xffff0000;
  456.     temppc=(immd<<2);
  457.   }
  458.   else temppc=immd<<2;
  459.   temppc=(pc+4)+temppc;
  460.  
  461.   switch(rt){
  462.   case 000:/* BLTZ */
  463.     sprintf(insn_buf,"bltz\t%s,0x%08x\n",regn[rs],(long)temppc);
  464.     break;
  465.   case 001:/* BGEZ */
  466.     sprintf(insn_buf,"bgez\t%s,0x%08x\n",regn[rs],(long)temppc);
  467.     break;
  468.   case 002:/* BLTZL */
  469.     sprintf(insn_buf,"bltzl\t%s,0x%08x\n",regn[rs],(long)temppc);
  470.     break;
  471.   case 003:/* BGEZL */
  472.     sprintf(insn_buf,"bgezl\t%s,0x%08x\n",regn[rs],(long)temppc);
  473.     break;
  474.   case 010:/* TGEI */
  475.     sprintf(insn_buf,"tgei\t%s,0x%04x\n",regn[rs],immd&0xffff);
  476.     break;
  477.   case 011:/* TGEIU */
  478.     sprintf(insn_buf,"tgeiu\t%s,0x%04x\n",regn[rs],immd&0xffff);
  479.     break;
  480.   case 012:/* TLTI */
  481.     sprintf(insn_buf,"tlti\t%s,0x%04x\n",regn[rs],immd&0xffff);
  482.     break;
  483.   case 013:/* TLTIU */
  484.     sprintf(insn_buf,"tltiu\t%s,0x%04x\n",regn[rs],immd&0xffff);
  485.     break;
  486.   case 014:/* TEQI */
  487.     sprintf(insn_buf,"teqi\t%s,0x%04x\n",regn[rs],immd&0xffff);
  488.     break;
  489.   case 016:/* TNEI */
  490.     sprintf(insn_buf,"tnei\t%s,0x%04x\n",regn[rs],immd&0xffff);
  491.     break;
  492.   case 020:/* BLTZAL */
  493.     sprintf(insn_buf,"bltzal\t%s,0x%08x\n",regn[rs],(long)temppc);
  494.     break;
  495.   case 021:/* BGEZAL */
  496.     sprintf(insn_buf,"bgezal\t%s,0x%08x\n",regn[rs],(long)temppc);
  497.     break;
  498.   case 022:/* BLTZALL */
  499.     sprintf(insn_buf,"bltzall\t%s,0x%08x\n",regn[rs],(long)temppc);
  500.     break;
  501.   case 023:/* BGEZALL */
  502.     sprintf(insn_buf,"bgezall\t%s,0x%08x\n",regn[rs],(long)temppc);
  503.     break;
  504.   default:
  505.     sprintf(insn_buf,".word\t0x%08x\n",(long)opcode);
  506.   }
  507. }
  508.  
  509. static void dis_cop1x(int rs,int rt,int rd,int sa,int func,int immd,ulong targ,ulong pc)
  510. {
  511.   switch(func){
  512.   case 000:
  513.     sprintf(insn_buf,"lwxc1\tfp%d,%s(%s)\n",rd,regn[rt],regn[rs]);
  514.     break;
  515.   case 001:
  516.     sprintf(insn_buf,"ldxc1\tfp%d,%s(%s)\n",rd,regn[rt],regn[rs]);
  517.     break;
  518.   case 010:
  519.     sprintf(insn_buf,"swxc1\tfp%d,%s(%s)\n",rd,regn[rt],regn[rs]);
  520.     break;
  521.   case 011:
  522.     sprintf(insn_buf,"sdxc1\tfp%d,%s(%s)\n",rd,regn[rt],regn[rs]);
  523.     break;
  524.   case 017:
  525.     if(((rd>=0)&&(rd<=7))||(rd==25))
  526.       sprintf(insn_buf,"prefx\t%s,%s(%s)\n",pref_hint[rd],regn[rt],regn[rs]);
  527.     else
  528.       sprintf(insn_buf,"prefx\t%d,%s(%s)\n",rd,regn[rt],regn[rs]);
  529.     break;
  530.   case 040:
  531.   case 041:
  532.   case 050:
  533.   case 051:
  534.   case 060:
  535.   case 061:
  536.   case 070:
  537.   case 071:
  538.     sprintf(insn_buf,"%s.%c\tfp%d,fp%d,fp%d,fp%d\n",
  539.         macc_nam[(func>>3)-4],
  540.         (func&1)? 'd' : 's',
  541.         sa,rs,rd,rt);
  542.     break;
  543.   default:
  544.       sprintf(insn_buf,".word\t0x%08x\n",opcode);
  545.   }
  546. }
  547.  
  548. static void dis_copz(int cn,int rs,int rt,int rd,int sa,int func,int immd,ulong targ,ulong pc)
  549. {
  550.   ulong    temppc;
  551.   if(immd&0x8000) temppc=0xfffc|(immd<<2);
  552.   else temppc=immd<<2;
  553.   temppc=(pc+4)+temppc;
  554.  
  555.   if(cn==0){/* COP0 */
  556.     switch(rs){
  557.     case 000:/* MF */
  558.       sprintf(insn_buf,"mfc0\t%s,%s\n",regn[rt],cregn[rd]);
  559.       break;
  560.     case 001:/* DMF */
  561.       sprintf(insn_buf,"dmfc0\t%s,%s\n",regn[rt],cregn[rd]);
  562.       break;
  563.     case 002:/* CF */
  564.       sprintf(insn_buf,"cfc0\t%s,%s\n",regn[rt],cregn[rd]);
  565.       break;
  566.     case 004:/* MT */
  567.       sprintf(insn_buf,"mtc0\t%s,%s\n",regn[rt],cregn[rd]);
  568.       break;
  569.     case 005:/* DMT */
  570.       sprintf(insn_buf,"dmtc0\t%s,%s\n",regn[rt],cregn[rd]);
  571.       break;
  572.     case 006:/* CT */
  573.       sprintf(insn_buf,"ctc0\t%s,%s\n",regn[rt],cregn[rd]);
  574.       break;
  575.     case 010:/* BC */
  576.       if(rt==0)
  577.     sprintf(insn_buf,"bc0f\t0x%08x\n",(long)temppc);
  578.       else if(rt==1)
  579.     sprintf(insn_buf,"bc0t\t0x%08x\n",(long)temppc);
  580.       else if(rt==2)
  581.     sprintf(insn_buf,"bc0fl\t0x%08x\n",(long)temppc);
  582.       else if(rt==3)
  583.     sprintf(insn_buf,"bc0tl\t0x%08x\n",(long)temppc);
  584.       else
  585.     sprintf(insn_buf,".word\t0x%08x\n",(long)opcode);
  586.       break;
  587.     case 020:
  588.     case 021:
  589.     case 022:
  590.     case 023:
  591.     case 024:
  592.     case 025:
  593.     case 026:
  594.     case 027:
  595.     case 030:
  596.     case 031:
  597.     case 032:
  598.     case 033:
  599.     case 034:
  600.     case 035:
  601.     case 036:
  602.     case 037:/* CO */
  603.       switch(func){
  604.       case 001:/* TLBR */
  605.     sprintf(insn_buf,"tlbr\n"); break;
  606.       case 002:/* TLBWI */
  607.     sprintf(insn_buf,"tlbwi\n"); break;
  608.       case 006:/* TLBWR */
  609.     sprintf(insn_buf,"tlbwr\n"); break;
  610.       case 010:/* TLBP */
  611.     sprintf(insn_buf,"tlbp\n"); break;
  612.       case 020:/* RFE */
  613.     sprintf(insn_buf,"rfe\n"); break;
  614.       case 030:/* ERET */
  615.     sprintf(insn_buf,"eret\n"); break;
  616.       default:
  617.     sprintf(insn_buf,".word\t0x%08x\n",opcode);
  618.       }
  619.       break;
  620.     default:
  621.       sprintf(insn_buf,".word\t0x%08x\n",opcode);
  622.     }
  623.   }
  624.   else if(cn==1){
  625.     dis_cp1(rs,rt,rd,sa,func,pc);
  626.   }
  627.   else if(cn==2){/* COP2 */
  628.     switch(rs&0xf){
  629.     case 000:/* MF */
  630.       sprintf(insn_buf,"mfc2\tr%d,r%d\n",rt,rd&0x1f);
  631.       break;
  632.     case 001:/* DMF */
  633.       sprintf(insn_buf,"dmfc2\tr%d,r%d\n",rt,rd&0x1f);
  634.       break;
  635.     case 002:/* CF */
  636.       sprintf(insn_buf,"cfc2\tr%d,r%d\n",rt,rd&0x1f);
  637.       break;
  638.     case 004:/* MT */
  639.       sprintf(insn_buf,"mtc2\tr%d,r%d\n",rt,rd&0x1f);
  640.       break;
  641.     case 005:/* DMT */
  642.       sprintf(insn_buf,"dmtc2\tr%d,r%d\n",rt,rd&0x1f);
  643.       break;
  644.     case 006:/* CT */
  645.       sprintf(insn_buf,"ctc2\tr%d,r%d\n",rt,rd&0x1f);
  646.       break;
  647.     case 010:/* BC */
  648.       if(rt==0)
  649.         sprintf(insn_buf,"bc2f\t0x%08x\n",(long)temppc);
  650.       else if(rt==1)
  651.         sprintf(insn_buf,"bc2t\t0x%08x\n",(long)temppc);
  652.       else if(rt==2)
  653.         sprintf(insn_buf,"bc2fl\t0x%08x\n",(long)temppc);
  654.       else if(rt==3)
  655.         sprintf(insn_buf,"bc2tl\t0x%08x\n",(long)temppc);
  656.       else
  657.         sprintf(insn_buf,".word\t0x%08x\n",(long)opcode);
  658.       break;
  659.     default:
  660.       sprintf(insn_buf,".word\t0x%08x\n",(long)opcode);
  661.     }
  662.   }
  663.   else if(cn==3){/* COP3 */
  664.     switch(rs&0xf){
  665.     case 000:/* MF */
  666.       sprintf(insn_buf,"mfc3\tr%d,r%d\n",rt,rd&0x1f);
  667.       break;
  668.     case 001:/* DMF */
  669.       sprintf(insn_buf,"dmfc3\tr%d,r%d\n",rt,rd&0x1f);
  670.       break;
  671.     case 002:/* CF */
  672.       sprintf(insn_buf,"cfc3\tr%d,r%d\n",rt,rd&0x1f);
  673.       break;
  674.     case 004:/* MT */
  675.       sprintf(insn_buf,"mtc3\tr%d,r%d\n",rt,rd&0x1f);
  676.       break;
  677.     case 005:/* DMT */
  678.       sprintf(insn_buf,"dmtc3\tr%d,r%d\n",rt,rd&0x1f);
  679.       break;
  680.     case 006:/* CT */
  681.       sprintf(insn_buf,"ctc3\tr%d,r%d\n",rt,rd&0x1f);
  682.       break;
  683.     case 010:/* BC */
  684.       if(rt==0)
  685.         sprintf(insn_buf,"bc3f\t0x%08x\n",(long)temppc);
  686.       else if(rt==1)
  687.         sprintf(insn_buf,"bc3t\t0x%08x\n",(long)temppc);
  688.       else if(rt==2)
  689.         sprintf(insn_buf,"bc3fl\t0x%08x\n",(long)temppc);
  690.       else if(rt==3)
  691.         sprintf(insn_buf,"bc3tl\t0x%08x\n",(long)temppc);
  692.       else
  693.         sprintf(insn_buf,".word\t0x%08x\n",(long)opcode);
  694.       break;
  695.     default:
  696.       sprintf(insn_buf,".word\t0x%08x\n",(long)opcode);
  697.     }
  698.   }
  699.   else {
  700.     sprintf(insn_buf,".word\t0x%08x\n",opcode);
  701.   }
  702. }
  703.  
  704. static void dis_cache(int ca,int opr,int base,long offset,ulong pc)
  705. {
  706.   static char    *c[4]={"I","D","SI","SD"};
  707.   static char    *operation;
  708.   switch(opr){
  709.   case 0:
  710.     if(ca==0||ca==2)
  711.       operation="Index_Inv";
  712.     else
  713.       operation="Index_Writeback_Inv";
  714.     break;
  715.   case 1:
  716.     operation="Index_Load_Tag";
  717.     break;
  718.   case 2:
  719.     operation="Index_Store_Tag";
  720.     break;
  721.   case 3:
  722.     operation="Create_Dirty";
  723.     break;
  724.   case 4:
  725.     operation="Hit_Inv";
  726.     break;
  727.   case 5:
  728.     if(ca==0)
  729.       operation="Fill";
  730.     else
  731.       operation="Hit_Writeback_Inv";
  732.     break;
  733.   case 6:
  734.     operation="Hit_Writeback";
  735.     break;
  736.   case 7:
  737.     operation="Hit_Set_Virtual";
  738.     break;
  739.   }
  740.   sprintf(insn_buf,"cache\t%s_%s,%d(%s)\n",
  741.      operation,
  742.      c[ca],
  743.      offset,
  744.      regn[base]            );
  745. }
  746.  
  747. static void dis_special2(int rs, int rt, int rd, int func)
  748. {
  749.   switch(func){
  750.   case 000:/* MADD */
  751.     sprintf(insn_buf,"madd\t%s,%s\n",regn[rs],regn[rt]);
  752.     break;
  753.   case 001:/* MADDU */
  754.     sprintf(insn_buf,"maddu\t%s,%s\n",regn[rs],regn[rt]);
  755.     break;
  756.   case 002:/* MUL */
  757.     sprintf(insn_buf,"mul\t%s,%s,%s\n",regn[rd],regn[rs],regn[rt]);
  758.     break;
  759.   case 004:/* MSUB */
  760.     sprintf(insn_buf,"msub\t%s,%s\n",regn[rs],regn[rt]);
  761.     break;
  762.   case 005:/* MSUBU */
  763.     sprintf(insn_buf,"msubu\t%s,%s\n",regn[rs],regn[rt]);
  764.     break;
  765.   case 040:/* CLZ */
  766.     sprintf(insn_buf,"clz\t%s,%s\n",regn[rt],regn[rs]);
  767.     break;
  768.   case 041:/* CLO */
  769.     sprintf(insn_buf,"clo\t%s,%s\n",regn[rt],regn[rs]);
  770.     break;
  771.   case 044:/* DCLZ */
  772.     sprintf(insn_buf,"dclz\t%s,%s\n",regn[rt],regn[rs]);
  773.     break;
  774.   case 045:/* DCLO */
  775.     sprintf(insn_buf,"dclo\t%s,%s\n",regn[rt],regn[rs]);
  776.     break;
  777.   case 077:/* SSNOP */
  778.     sprintf(insn_buf,"ssnop\n");
  779.     break;
  780.   default:
  781.     sprintf(insn_buf,".word\t0x%08x\n",(long)opcode);
  782.   }
  783. }
  784.  
  785. static void dis_mips(ulong insn,ulong pc)
  786. {
  787.   int    op,rs,rt,rd,sa,func,immd,targ;
  788.   ulong temppc;
  789.  
  790.   if(insn==0){
  791.     printf("%08x %08x : nop\n",pc,opcode);
  792.     return;
  793.   }
  794.   op=(insn>>26)&0x3f;
  795.   rs=(insn>>21)&0x1f;
  796.   rt=(insn>>16)&0x1f;
  797.   rd=(insn>>11)&0x1f;
  798.   sa=(insn>> 6)&0x1f;
  799.   func=insn&0x3f;
  800.   immd=insn&0xffff;
  801.   targ=insn&0x3ffffff;
  802. #if 0
  803.   printf("op=%02x rs=%02x rt=%02x rd=%02x sa=%02x func=%02x immd=%04x targ=%07x\n",
  804.      op,rs,rt,rd,sa,func,immd,targ);
  805. #endif
  806.   switch(op){
  807.   case 000:/* SPECIAL */
  808.     dis_special(rs,rt,rd,sa,func,immd,targ,pc);
  809.     break;
  810.   case 001:/* BCOND */
  811.     dis_bcond(rs,rt,rd,sa,func,immd,targ,pc);
  812.     break;
  813.   case 002:/* J */
  814.   case 003:/* JAL */
  815.     temppc=(pc&0xf0000000)|(targ<<2);
  816.     sprintf(insn_buf,"%s\t0x%08x\n",jnam[op-2],(long)temppc);
  817.     break;
  818.   case 004:/* BEQ */
  819.   case 005:/* BNE */
  820.   case 006:/* BLEZ */
  821.   case 007:/* BGTZ */
  822.     if(immd&0x8000) temppc=0xfffc0000|(immd<<2);
  823.     else temppc=immd<<2;
  824.     temppc=(pc+4)+temppc;
  825.     sprintf(insn_buf,"%s\t%s,%s,0x%08x\n",bnam[op-4],regn[rs],regn[rt],(long)temppc);
  826.     break;
  827.   case 010:/* ADDI */
  828.   case 011:/* ADDIU */
  829.   case 012:/* SLTI */
  830.   case 013:/* SLTIU */
  831.     if(immd&0x8000) immd=0xffff0000|immd;
  832.     if(immd<0)
  833.       sprintf(insn_buf,"%s\t%s,%s,-0x%04x\n",inam[op-010],regn[rt],regn[rs],-immd);
  834.     else
  835.       sprintf(insn_buf,"%s\t%s,%s,0x%04x\n",inam[op-010],regn[rt],regn[rs],immd&0xffff);
  836.     break;
  837.   case 014:/* ANDI */
  838.   case 015:/* ORI */
  839.   case 016:/* XORI */
  840.     sprintf(insn_buf,"%s\t%s,%s,0x%04x\n",inam[op-010],regn[rt],regn[rs],immd&0xffff);
  841.     break;
  842.   case 017:/* LUI */
  843.     sprintf(insn_buf,"lui\t%s,0x%04x\n",regn[rt],immd&0xffff);
  844.     break;
  845.   case 020:/* COP0 */
  846.   case 021:/* COP1 */
  847.   case 022:/* COP2 */
  848.     dis_copz(op-020,rs,rt,rd,sa,func,immd,targ,pc);
  849.     break;
  850.   case 023:/* COP3 */
  851.     if(ty_mips==MIPS4)
  852.       dis_cop1x(rs,rt,rd,sa,func,immd,targ,pc);
  853.     else
  854.       dis_copz(op-020,rs,rt,rd,sa,func,immd,targ,pc);
  855.     break;
  856.   case 024:/* BEQL */
  857.   case 025:/* BNEL */
  858.   case 026:/* BLEZL */
  859.   case 027:/* BGTZL */
  860.     if(immd&0x8000) temppc=0xfffc0000|(immd<<2);
  861.     else temppc=immd<<2;
  862.     temppc=(pc+4)+temppc;
  863.     sprintf(insn_buf,"%sl\t%s,%s,0x%08x\n",bnam[op-024],regn[rs],regn[rt],(long)temppc);
  864.     break;
  865.   case 030:/* DADDI */
  866.   case 031:/* DADDU */
  867.     if(immd&0x8000) immd=0xffff0000|immd;
  868.     if(immd<0)
  869.       sprintf(insn_buf,"%s\t%s,%s,-0x%04x\n",
  870.          (op==030)? "daddi" : "daddiu",
  871.          regn[rt],regn[rs],-immd);
  872.     else
  873.       sprintf(insn_buf,"%s\t%s,%s,0x%04x\n",
  874.          (op==030)? "daddi" : "daddiu",
  875.          regn[rt],regn[rs],immd&0xffff);
  876.     break;
  877.   case 032:/* LDL */
  878.   case 033:/* LDR */
  879.     if(immd&0x8000) immd=0xffff0000|immd;
  880.     sprintf(insn_buf,"%s\t%s,%d(%s)\n",
  881.        (op==032)? "ldl" : "ldr",
  882.        regn[rt],immd,regn[rs]);
  883.     break;
  884.   case 034:/* Special2 */
  885.     dis_special2(rs,rt,rd,func);
  886.     break;
  887.   case 035:/* JALX */
  888.     temppc=(pc&0xf0000000)|(targ<<2);
  889.     sprintf(insn_buf,"jalx\t0x%08x\n",(long)temppc);
  890.     break;
  891.   case 040:/* LB */
  892.   case 041:/* LH */
  893.   case 042:/* LWL */
  894.   case 043:/* LW */
  895.   case 044:/* LBU */
  896.   case 045:/* LHU */
  897.   case 046:/* LWR */
  898.   case 047:/* LWU */
  899.   case 050:/* SB */
  900.   case 051:/* SH */
  901.   case 052:/* SWL */
  902.   case 053:/* SW */
  903.   case 054:/* SDL */
  904.   case 055:/* SDR */
  905.   case 056:/* SWR */
  906.     if(immd&0x8000) immd=0xffff0000|immd;
  907.     sprintf(insn_buf,"%s\t%s,%d(%s)\n",lsnam[op-040],regn[rt],immd,regn[rs]);
  908.     break;
  909.   case 057:/* CACHE */
  910.     if(immd&0x8000) immd=0xffff0000|immd;
  911.     dis_cache(rt&3/*cache*/,
  912.           (rt>>2)/*operation*/,
  913.           rs/*base*/,
  914.           immd,
  915.           pc);
  916.     break;
  917.   case 060:/* LCW0 */
  918.     if(immd&0x8000) immd=0xffff0000|immd;
  919.     if(ty_mips==MIPS1)
  920.       sprintf(insn_buf,"lwc0\t%s,%d(%s)\n",
  921.          cregn[rt],immd,regn[rs]);
  922.     else
  923.       sprintf(insn_buf,"ll\t%s,%d(%s)\n",
  924.          regn[rt],immd,regn[rs]);
  925.     break;
  926.   case 061:/* LCW1 */
  927.     if(immd&0x8000) immd=0xffff0000|immd;
  928.     sprintf(insn_buf,"lwc%d\tfp%d,%d(%s)\n",op-060,rt&0x1f,immd,regn[rs]);
  929.     break;
  930.   case 062:/* LCW2 */
  931.     if(immd&0x8000) immd=0xffff0000|immd;
  932.     sprintf(insn_buf,"lwc%d\tr%d,%d(%s)\n",op-060,rt,immd,regn[rs]);
  933.     break;
  934.   case 063:/* LCW3 */
  935.     if(immd&0x8000) immd=0xffff0000|immd;
  936.     if(ty_mips==MIPS4){ /* PREF */
  937.       switch(rt){
  938.       case 0:
  939.       case 1:
  940.       case 4:
  941.       case 5:
  942.       case 6:
  943.       case 7:
  944.       case 25:
  945.     sprintf(insn_buf,"pref\t%s,%d(%s)\n",pref_hint[rt],immd,regn[rs]);
  946.     break;
  947.       default:
  948.     sprintf(insn_buf,"pref\t%d,%d(%s)\n",rt,immd,regn[rs]);
  949.       }
  950.     }
  951.     else{
  952.       sprintf(insn_buf,"lwc%d\tr%d,%d(%s)\n",op-060,rt,immd,regn[rs]);
  953.     }
  954.     break;
  955.   case 064:/* LLD  */
  956.     if(immd&0x8000) immd=0xffff0000|immd;
  957.     sprintf(insn_buf,"lld\t%s,%d(%s)\n",regn[rt],immd,regn[rs]);
  958.     break;
  959.   case 065:/* LCD1 */
  960.     if(immd&0x8000) immd=0xffff0000|immd;
  961.     sprintf(insn_buf,"ldc%d\tfp%d,%d(%s)\n",op-064,rt&0x1f,immd,regn[rs]);
  962.     break;
  963.   case 066:/* LCD2 */
  964.     if(immd&0x8000) immd=0xffff0000|immd;
  965.     sprintf(insn_buf,"ldc%d\tr%d,%d(%s)\n",op-064,rt,immd,regn[rs]);
  966.     break;
  967.   case 067:/* LD */
  968.     if(immd&0x8000) immd=0xffff0000|immd;
  969.     sprintf(insn_buf,"ld\t%s,%d(%s)\n",regn[rt],immd,regn[rs]);
  970.     break;
  971.   case 070:/* SCW0 */
  972.     if(immd&0x8000) immd=0xffff0000|immd;
  973.     if(ty_mips==MIPS1)
  974.       sprintf(insn_buf,"swc0\t%s,%d(%s)\n",
  975.          cregn[rt],immd,regn[rs]);
  976.     else
  977.       sprintf(insn_buf,"sc\t%s,%d(%s)\n",
  978.          regn[rt],immd,regn[rs]);
  979.     break;
  980.   case 071:/* SCW1 */
  981.     if(immd&0x8000) immd=0xffff0000|immd;
  982.     sprintf(insn_buf,"swc%d\tfp%d,%d(%s)\n",op-070,rt&0x1f,immd,regn[rs]);
  983.     break;
  984.   case 072:/* SCW2 */
  985.   case 073:/* SCW3 */
  986.     if(immd&0x8000) immd=0xffff0000|immd;
  987.     sprintf(insn_buf,"swc%d\tr%d,%d(%s)\n",op-070,rt,immd,regn[rs]);
  988.     break;
  989.   case 074:/* SCD  */
  990.     if(immd&0x8000) immd=0xffff0000|immd;
  991.     sprintf(insn_buf,"scd\t%s,%d(%s)\n",
  992.        regn[rt],immd,regn[rs]);
  993.     break;
  994.   case 075:/* SCD1 */
  995.     if(immd&0x8000) immd=0xffff0000|immd;
  996.     sprintf(insn_buf,"sdc%d\tfp%d,%d(%s)\n",op-074,rt&0x1f,immd,regn[rs]);
  997.     break;
  998.   case 076:/* SCD2 */
  999.     if(immd&0x8000) immd=0xffff0000|immd;
  1000.     sprintf(insn_buf,"sdc%d\tr%d,%d(%s)\n",op-074,rt,immd,regn[rs]);
  1001.     break;
  1002.   case 077:/* SD */
  1003.     if(immd&0x8000) immd=0xffff0000|immd;
  1004.     sprintf(insn_buf,"sd\t%s,%d(%s)\n",regn[rt],immd,regn[rs]);
  1005.     break;
  1006.   default:
  1007.     sprintf(insn_buf,".word\t0x%08x\n",opcode);
  1008.   }
  1009.   printf("%08x %08x : %s",pc,opcode,insn_buf);
  1010. }
  1011. /*****************************************************************/
  1012. static int dis_jal_flag = 0;
  1013. static int dis_extend_flag = 0;
  1014. static ulong dis_extend_inst;
  1015.  
  1016. static int mips16_reg_get(int reg)
  1017. {
  1018.   if(reg==0) return 16;
  1019.   if(reg==1) return 17;
  1020.   return reg;
  1021. }
  1022.  
  1023. static void dis_mips16_RR(ulong decRR, ulong decRX, ulong decRY, ulong decSA, ulong insn)
  1024. {
  1025.   switch(decRR){
  1026.   case 000:/* j(al)r */
  1027.     if(dis_extend_flag){
  1028.       sprintf(insn_buf,"reserved(RR)\n");
  1029.     }
  1030.     else{
  1031.       switch(decRY&0x7){
  1032.       case 0:/* jr rx */
  1033.     sprintf(insn_buf,"jr\tr%d\n",decRX);
  1034.     break;
  1035.       case 1:
  1036.     if(decRX==16)
  1037.       sprintf(insn_buf,"jr\tra\n");
  1038.     else
  1039.       sprintf(insn_buf,"reserved(RR)\n");
  1040.     break;
  1041.       case 2:
  1042.     sprintf(insn_buf,"jalr\tra,r%d\n",decRX);
  1043.     break;
  1044.       default:
  1045.     sprintf(insn_buf,"reserved(RR)\n");
  1046.       }
  1047.     }
  1048.     break;
  1049.   case 001:
  1050.     sprintf(insn_buf,"reserved(RR)\n");
  1051.     break;
  1052.   case 002:/* slt */
  1053.     if(dis_extend_flag){
  1054.       sprintf(insn_buf,"reserved(RR)\n");
  1055.     }
  1056.     else{
  1057.       sprintf(insn_buf,"slt\tr%d,r%d\n",decRX,decRY);
  1058.     }
  1059.     break;
  1060.   case 003:/* sltu */
  1061.     if(dis_extend_flag){
  1062.       sprintf(insn_buf,"reserved(RR)\n");
  1063.     }
  1064.     else{
  1065.       sprintf(insn_buf,"sltu\tr%d,r%d\n",decRX,decRY);
  1066.     }
  1067.     break;
  1068.   case 004:/* sllv */
  1069.     if(dis_extend_flag){
  1070.       sprintf(insn_buf,"reserved(RR)\n");
  1071.     }
  1072.     else{
  1073.       sprintf(insn_buf,"sllv\tr%d,r%d\n",decRY,decRX);
  1074.     }
  1075.     break;
  1076.   case 005:/* break */
  1077.     if(dis_extend_flag){
  1078.       sprintf(insn_buf,"reserved(RR)\n");
  1079.     }
  1080.     else{
  1081.       sprintf(insn_buf,"break\t0x%x\n",((decRX&7)<<3)|(decRY&7));
  1082.     }
  1083.     break;
  1084.   case 006:/* srlv */
  1085.     if(dis_extend_flag){
  1086.       sprintf(insn_buf,"reserved(RR)\n");
  1087.     }
  1088.     else{
  1089.       sprintf(insn_buf,"srlv\tr%d,r%d\n",decRY,decRX);
  1090.     }
  1091.     break;
  1092.   case 007:/* srav */
  1093.     if(dis_extend_flag){
  1094.       sprintf(insn_buf,"reserved(RR)\n");
  1095.     }
  1096.     else{
  1097.       sprintf(insn_buf,"srav\tr%d,r%d\n",decRY,decRX);
  1098.     }
  1099.     break;
  1100.   case 010:/* dsrl */
  1101.     if(dis_extend_flag){
  1102.       decSA=(insn&0x20)|((insn>>6)&0x1f);
  1103.     }
  1104.     else{
  1105.       decRX &= 7;
  1106.       if(decRX==0)
  1107.     decSA=8;
  1108.       else
  1109.     decSA=decRX;
  1110.     }
  1111.     sprintf(insn_buf,"dsrl\tr%d,%d\n",decRY,decSA);
  1112.     break;
  1113.   case 011:/* syscall */
  1114.     if(dis_extend_flag){
  1115.       sprintf(insn_buf,"reserved(RR)\n");
  1116.     }
  1117.     else{
  1118.       sprintf(insn_buf,"syscall\t0x%x\n",((decRX&7)<<3)|(decRY&7));
  1119.     }
  1120.     break;
  1121.   case 012:/* cmp */
  1122.     if(dis_extend_flag){
  1123.       sprintf(insn_buf,"reserved(RR)\n");
  1124.     }
  1125.     else{
  1126.       sprintf(insn_buf,"cmp\tr%d,r%d\n",decRX,decRY);
  1127.     }
  1128.     break;
  1129.   case 013:/* neg */
  1130.     if(dis_extend_flag){
  1131.       sprintf(insn_buf,"reserved(RR)\n");
  1132.     }
  1133.     else{
  1134.       sprintf(insn_buf,"neg\tr%d,r%d\n",decRX,decRY);
  1135.     }
  1136.     break;
  1137.   case 014:/* and */
  1138.     if(dis_extend_flag){
  1139.       sprintf(insn_buf,"reserved(RR)\n");
  1140.     }
  1141.     else{
  1142.       sprintf(insn_buf,"and\tr%d,r%d\n",decRX,decRY);
  1143.     }
  1144.     break;
  1145.   case 015:/* or */
  1146.     if(dis_extend_flag){
  1147.       sprintf(insn_buf,"reserved(RR)\n");
  1148.     }
  1149.     else{
  1150.       sprintf(insn_buf,"or\tr%d,r%d\n",decRX,decRY);
  1151.     }
  1152.     break;
  1153.   case 016:/* xor */
  1154.     if(dis_extend_flag){
  1155.       sprintf(insn_buf,"reserved(RR)\n");
  1156.     }
  1157.     else{
  1158.       sprintf(insn_buf,"xor\tr%d,r%d\n",decRX,decRY);
  1159.     }
  1160.     break;
  1161.   case 017:/* not */
  1162.     if(dis_extend_flag){
  1163.       sprintf(insn_buf,"reserved(RR)\n");
  1164.     }
  1165.     else{
  1166.       sprintf(insn_buf,"not\tr%d,r%d\n",decRX,decRY);
  1167.     }
  1168.     break;
  1169.   case 020:/* mfhi */
  1170.     if(dis_extend_flag){
  1171.       sprintf(insn_buf,"reserved(RR)\n");
  1172.     }
  1173.     else{
  1174.       if(decRY&7)
  1175.     sprintf(insn_buf,"reserved(RR)\n");
  1176.       else
  1177.     sprintf(insn_buf,"mfhi\tr%d\n",decRX);
  1178.     }
  1179.     break;
  1180.   case 021:
  1181.     sprintf(insn_buf,"reserved(RR)\n");
  1182.     break;
  1183.   case 022:/* mflo */
  1184.     if(dis_extend_flag){
  1185.       sprintf(insn_buf,"reserved(RR)\n");
  1186.     }
  1187.     else{
  1188.       if(decRY&7)
  1189.     sprintf(insn_buf,"reserved(RR)\n");
  1190.       else
  1191.     sprintf(insn_buf,"mflo\tr%d\n",decRX);
  1192.     }
  1193.     break;
  1194.   case 023:/* dsra */
  1195.     if(dis_extend_flag){
  1196.       decSA=(insn&0x20)|((insn>>6)&0x1f);
  1197.     }
  1198.     else{
  1199.       decRX &= 7;
  1200.       if(decRX==0)
  1201.     decSA=8;
  1202.       else
  1203.     decSA=decRX;
  1204.     }
  1205.     sprintf(insn_buf,"dsra\tr%d,%d\n",decRY,decSA);
  1206.     break;
  1207.   case 024:/* dsllv */
  1208.     if(dis_extend_flag){
  1209.       sprintf(insn_buf,"reserved(RR)\n");
  1210.     }
  1211.     else{
  1212.       sprintf(insn_buf,"dsllv\tr%d,r%d\n",decRY,decRX);
  1213.     }
  1214.     break;
  1215.   case 025:
  1216.     sprintf(insn_buf,"reserved(RR)\n");
  1217.     break;
  1218.   case 026:/* dsrlv */
  1219.     if(dis_extend_flag){
  1220.       sprintf(insn_buf,"reserved(RR)\n");
  1221.     }
  1222.     else{
  1223.       sprintf(insn_buf,"dsrlv\tr%d,r%d\n",decRY,decRX);
  1224.     }
  1225.     break;
  1226.   case 027:/* dsrav */
  1227.     if(dis_extend_flag){
  1228.       sprintf(insn_buf,"reserved(RR)\n");
  1229.     }
  1230.     else{
  1231.       sprintf(insn_buf,"dsrav\tr%d,r%d\n",decRY,decRX);
  1232.     }
  1233.     break;
  1234.   case 030:/* mult */
  1235.     if(dis_extend_flag){
  1236.       sprintf(insn_buf,"reserved(RR)\n");
  1237.     }
  1238.     else{
  1239.       sprintf(insn_buf,"mult\tr%d,r%d\n",decRX,decRY);
  1240.     }
  1241.     break;
  1242.   case 031:/* multu */
  1243.     if(dis_extend_flag){
  1244.       sprintf(insn_buf,"reserved(RR)\n");
  1245.     }
  1246.     else{
  1247.       sprintf(insn_buf,"multu\tr%d,r%d\n",decRX,decRY);
  1248.     }
  1249.     break;
  1250.   case 032:/* div */
  1251.     if(dis_extend_flag){
  1252.       sprintf(insn_buf,"reserved(RR)\n");
  1253.     }
  1254.     else{
  1255.       sprintf(insn_buf,"div\tr%d,r%d\n",decRX,decRY);
  1256.     }
  1257.     break;
  1258.   case 033:/* divu */
  1259.     if(dis_extend_flag){
  1260.       sprintf(insn_buf,"reserved(RR)\n");
  1261.     }
  1262.     else{
  1263.       sprintf(insn_buf,"divu\tr%d,r%d\n",decRX,decRY);
  1264.     }
  1265.     break;
  1266.   case 034:/* dmult */
  1267.     if(dis_extend_flag){
  1268.       sprintf(insn_buf,"reserved(RR)\n");
  1269.     }
  1270.     else{
  1271.       sprintf(insn_buf,"dmult\tr%d,r%d\n",decRX,decRY);
  1272.     }
  1273.     break;
  1274.   case 035:/* dmultu */
  1275.     if(dis_extend_flag){
  1276.       sprintf(insn_buf,"reserved(RR)\n");
  1277.     }
  1278.     else{
  1279.       sprintf(insn_buf,"dmultu\tr%d,r%d\n",decRX,decRY);
  1280.     }
  1281.     break;
  1282.   case 036:/* ddiv */
  1283.     if(dis_extend_flag){
  1284.       sprintf(insn_buf,"reserved(RR)\n");
  1285.     }
  1286.     else{
  1287.       sprintf(insn_buf,"ddiv\tr%d,r%d\n",decRX,decRY);
  1288.     }
  1289.     break;
  1290.   case 037:/* ddivu */
  1291.     if(dis_extend_flag){
  1292.       sprintf(insn_buf,"reserved(RR)\n");
  1293.     }
  1294.     else{
  1295.       sprintf(insn_buf,"ddivu\tr%d,r%d\n",decRX,decRY);
  1296.     }
  1297.     break;
  1298.   }
  1299. }
  1300.  
  1301. static void dis_mips16_extend( ulong insn, ulong pc)
  1302. {
  1303.     ulong    decOP,decRX,decRY,decRZ,decSA,decFUNC,decRR,decIMMD,decIMMD5,decTARG,decCODE;
  1304.     ulong    temppc;
  1305.  
  1306.     insn = (insn<<16)|dis_extend_inst;
  1307. /*printf("insn32=%08x\n",insn);*/
  1308.     decOP    =               (insn>>(11+16))&0x1f;
  1309.     decRX    =mips16_reg_get((insn>>( 8+16))&0x7);
  1310.     decRY    =mips16_reg_get((insn>>( 5+16))&0x7);
  1311.     decRZ    =mips16_reg_get((insn>>( 2+16))&0x7);
  1312.     decSA    =               (insn>>( 2+16))&0x7;
  1313.     decFUNC    =               (insn>>    16 )&0x3;
  1314.     decRR    =               (insn>>    16 )&0x1f;
  1315.     decIMMD5=               (insn>>    16 )&0x1f;
  1316.     decSA   = (insn&0x400000)? (0x20|decSA):decSA;
  1317.     decIMMD = ((insn&0x1f)<<11)|(insn&0x7e0)|decIMMD5;
  1318.     decTARG    = decIMMD;
  1319.     decCODE    =               (insn>>( 5+16))&0x1f;
  1320.  
  1321.     if(dis_jal_flag)
  1322.       decOP = 003;
  1323.  
  1324.     switch(decOP){
  1325.     case 000:/* addiusp */
  1326.       if(decIMMD&0x8000)
  1327.         sprintf(insn_buf,"addiu\tr%d,sp,-0x%04x\n",decRX,-(long)(0xffff0000|decIMMD));
  1328.       else
  1329.         sprintf(insn_buf,"addiu\tr%d,sp,0x%04x\n",decRX,decIMMD);
  1330.       break;
  1331.     case 001:/* addiupc */
  1332.       if(decIMMD&0x8000)
  1333.         sprintf(insn_buf,"addiu\tr%d,pc,-0x%04x\n",decRX,-(long)(0xffff0000|decIMMD));
  1334.       else
  1335.         sprintf(insn_buf,"addiu\tr%d,pc,0x%04x\n",decRX,decIMMD);
  1336.       break;
  1337.     case 002:/* b */
  1338.       if(decTARG&0x8000)
  1339.         temppc=(0xffff0000|decTARG)<<1;
  1340.       else    temppc=decTARG<<1;
  1341.       temppc+=2+pc;
  1342.       sprintf(insn_buf,"b\t0x%08x\n",temppc);
  1343.       break;
  1344.     case 003:/* jal(x) */
  1345.       temppc=(pc&0xf0000000)|
  1346.               ((((insn&0x1f)<<21)|((insn&0x3e0)<<11)|((insn>>16)&0xffff))
  1347.            <<2);
  1348.       if(insn&0x400)/* jalx */
  1349.         sprintf(insn_buf,"jalx\t0x%08x\n",temppc);
  1350.       else /* jal */
  1351.         sprintf(insn_buf,"jal\t0x%08x\n",temppc);
  1352.       dis_jal_flag=0;
  1353.       break;
  1354.     case 004:/* beqz */
  1355.       if(decTARG&0x8000)
  1356.         temppc=(0xffff0000|decTARG)<<1;
  1357.       else    temppc=decTARG<<1;
  1358.       temppc+=2+pc;
  1359.       sprintf(insn_buf,"beqz\tr%d,0x%08x\n",decRX,temppc);
  1360.       break;
  1361.     case 005:/* bnez */
  1362.       if(decTARG&0x8000)
  1363.         temppc=(0xffff0000|decTARG)<<1;
  1364.       else    temppc=decTARG<<1;
  1365.       temppc+=2+pc;
  1366.       sprintf(insn_buf,"bnez\tr%d,0x%08x\n",decRX,temppc);
  1367.       break;
  1368.     case 006:/* SHIFT */
  1369.       decSA=((insn>>6)&0x1f)|((insn)&0x20);
  1370.       switch(decFUNC){
  1371.       case 0:/* sll  */
  1372.         sprintf(insn_buf,"sll\tr%d,r%d,%d\n",decRX,decRY,decSA);
  1373.         break;
  1374.       case 1:/* dsll */
  1375.         sprintf(insn_buf,"dsll\tr%d,r%d,%d\n",decRX,decRY,decSA);
  1376.         break;
  1377.       case 2:/* srl  */
  1378.         sprintf(insn_buf,"srl\tr%d,r%d,%d\n",decRX,decRY,decSA);
  1379.         break;
  1380.        default:/* sra */
  1381.         sprintf(insn_buf,"sra\tr%d,r%d,%d\n",decRX,decRY,decSA);
  1382.       }
  1383.       break;
  1384.     case 007:/* ld */
  1385.       if(decIMMD&0x8000)
  1386.         sprintf(insn_buf,"ld\tr%d,-0x%04x(r%d)\n",decRY,-(long)(0xffff0000|decIMMD),decRX);
  1387.       else
  1388.         sprintf(insn_buf,"ld\tr%d,0x%04x(r%d)\n",decRY,decIMMD,decRX);
  1389.       break;
  1390.     case 010:/* RRI-A */
  1391.       decIMMD=((insn&0xf)<<11)|(insn&0x7f0)|((insn>>16)&0xf);
  1392.       if(decRR&0x10){/* daddiu */
  1393.         if(decIMMD&0x4000)
  1394.           sprintf(insn_buf,"daddiu\tr%d,r%d,-0x%x\n",decRY,decRX,-(long)(0xffff8000|decIMMD));
  1395.         else
  1396.           sprintf(insn_buf,"daddiu\tr%d,r%d,0x%x\n",decRY,decRX,decIMMD);
  1397.       }
  1398.       else{/* addiu */
  1399.         if(decIMMD&0x4000)
  1400.           sprintf(insn_buf,"addiu\tr%d,r%d,-0x%x\n",decRY,decRX,-(long)(0xffff8000|decIMMD));
  1401.         else
  1402.           sprintf(insn_buf,"addiu\tr%d,r%d,0x%x\n",decRY,decRX,decIMMD);
  1403.       }
  1404.       break;
  1405.     case 011:/* addiu8 */
  1406.       if(decIMMD&0x8000)
  1407.         sprintf(insn_buf,"addiu\tr%d,-0x%04x\n",decRX,-(long)(0xffff0000|decIMMD));
  1408.       else
  1409.         sprintf(insn_buf,"addiu\tr%d,0x%04x\n",decRX,decIMMD);
  1410.       break;
  1411.     case 012:/* slti */
  1412.       if(decIMMD&0x8000)
  1413.         sprintf(insn_buf,"slti\tr%d,-0x%04x\n",decRX,-(long)(0xffff0000|decIMMD));
  1414.       else
  1415.         sprintf(insn_buf,"slti\tr%d,0x%04x\n",decRX,decIMMD);
  1416.       break;
  1417.     case 013:/* sltiu */
  1418.       if(decIMMD&0x8000)
  1419.         sprintf(insn_buf,"sltiu\tr%d,-0x%04x\n",decRX,-(long)(0xffff0000|decIMMD));
  1420.       else
  1421.         sprintf(insn_buf,"sltiu\tr%d,0x%04x\n",decRX,decIMMD);
  1422.       break;
  1423.     case 014:/* l8 */
  1424.       switch((insn>>(8+16))&7){
  1425.       case 0:/* bteqz */
  1426.         if(decTARG&0x8000)
  1427.           temppc=(0xffff0000|decTARG)<<1;
  1428.         else
  1429.           temppc=decTARG<<1;
  1430.         temppc+=2+pc;
  1431.         sprintf(insn_buf,"bteqz\t0x%08x\n",temppc);
  1432.         break;
  1433.       case 1:/* btnez */
  1434.         if(decTARG&0x8000)
  1435.           temppc=(0xffff0000|decTARG)<<1;
  1436.         else
  1437.           temppc=decTARG<<1;
  1438.         temppc+=2+pc;
  1439.         sprintf(insn_buf,"btnez\t0x%08x\n",temppc);
  1440.         break;
  1441.       case 2:/* swrasp */
  1442.         if(decIMMD&0x8000)
  1443.           sprintf(insn_buf,"sw\tra,-0x%04x(sp)\n",-(long)(0xffff0000|decIMMD));
  1444.         else
  1445.           sprintf(insn_buf,"sw\tra,0x%04x(sp)\n",decIMMD);
  1446.         break;
  1447.       case 3:/* adjsp */
  1448.         if(decIMMD&0x8000)
  1449.           sprintf(insn_buf,"addiu\tsp,-0x%04x\n",-(long)(0xffff0000|decIMMD));
  1450.         else
  1451.           sprintf(insn_buf,"addiu\tsp,0x%04x\n",decIMMD);
  1452.         break;
  1453.       case 4:
  1454.         sprintf(insn_buf,"reserved(I8)\n");
  1455.         break;
  1456.       case 5:/* mov32r */
  1457.         sprintf(insn_buf,"reserved(I8)\n");
  1458.         break;
  1459.       case 6:
  1460.         sprintf(insn_buf,"reserved(I8)\n");
  1461.         break;
  1462.       default:/* movr32 */
  1463.         sprintf(insn_buf,"reserved(I8)\n");
  1464.       }
  1465.       break;
  1466.     case 015:/* li */
  1467.           sprintf(insn_buf,"li\tr%d,0x%04x\n",decRX,decIMMD);
  1468.       break;
  1469.     case 016:/* cmpi */
  1470.       if(decIMMD&0x8000)
  1471.         sprintf(insn_buf,"cmpi\tr%d,-0x%04x\n",decRX,-(long)(0xffff0000|decIMMD));
  1472.       else
  1473.         sprintf(insn_buf,"cmpi\tr%d,0x%04x\n",decRX,decIMMD);
  1474.       break;
  1475.     case 017:/* sd */
  1476.       if(decIMMD&0x8000)
  1477.         sprintf(insn_buf,"sd\tr%d,-0x%04x(r%d)\n",decRY,-(long)(0xffff0000|decIMMD),decRX);
  1478.       else
  1479.         sprintf(insn_buf,"sd\tr%d,0x%04x(r%d)\n",decRY,decIMMD,decRX);
  1480.       break;
  1481.     case 020:/* lb */
  1482.       if(decIMMD&0x8000)
  1483.         sprintf(insn_buf,"lb\tr%d,-0x%04x(r%d)\n",decRY,-(long)(0xffff0000|decIMMD),decRX);
  1484.       else
  1485.         sprintf(insn_buf,"lb\tr%d,0x%04x(r%d)\n",decRY,decIMMD,decRX);
  1486.       break;
  1487.     case 021:/* lh */
  1488.       if(decIMMD&0x8000)
  1489.         sprintf(insn_buf,"lh\tr%d,-0x%04x(r%d)\n",decRY,-(long)(0xffff0000|decIMMD),decRX);
  1490.       else
  1491.         sprintf(insn_buf,"lh\tr%d,0x%04x(r%d)\n",decRY,decIMMD,decRX);
  1492.       break;
  1493.     case 022:/* lwsp */
  1494.       if(decIMMD&0x8000)
  1495.         sprintf(insn_buf,"lw\tr%d,-0x%04x(sp)\n",decRX,-(long)(0xffff0000|decIMMD));
  1496.       else
  1497.         sprintf(insn_buf,"lw\tr%d,0x%04x(sp)\n",decRX,decIMMD);
  1498.       break;
  1499.     case 023:/* lw */
  1500.       if(decIMMD&0x8000)
  1501.         sprintf(insn_buf,"lw\tr%d,-0x%04x(r%d)\n",decRY,-(long)(0xffff0000|decIMMD),decRX);
  1502.       else
  1503.         sprintf(insn_buf,"lw\tr%d,0x%04x(r%d)\n",decRY,decIMMD,decRX);
  1504.       break;
  1505.     case 024:/* lbu */
  1506.       if(decIMMD&0x8000)
  1507.         sprintf(insn_buf,"lbu\tr%d,-0x%04x(r%d)\n",decRY,-(long)(0xffff0000|decIMMD),decRX);
  1508.       else
  1509.         sprintf(insn_buf,"lbu\tr%d,0x%04x(r%d)\n",decRY,decIMMD,decRX);
  1510.       break;
  1511.     case 025:/* lhu */
  1512.       if(decIMMD&0x8000)
  1513.         sprintf(insn_buf,"lhu\tr%d,-0x%04x(r%d)\n",decRY,-(long)(0xffff0000|decIMMD),decRX);
  1514.       else
  1515.         sprintf(insn_buf,"lhu\tr%d,0x%04x(r%d)\n",decRY,decIMMD,decRX);
  1516.       break;
  1517.     case 026:/* lwpc */
  1518.       if(decIMMD&0x8000)
  1519.         sprintf(insn_buf,"lw\tr%d,-0x%04x(pc)\n",decRX,-(long)(0xffff0000|decIMMD));
  1520.       else
  1521.         sprintf(insn_buf,"lw\tr%d,0x%04x(pc)\n",decRX,decIMMD);
  1522.       break;
  1523.     case 027:/* lwu */
  1524.       if(decIMMD&0x8000)
  1525.         sprintf(insn_buf,"lwu\tr%d,-0x%04x(r%d)\n",decRY,-(long)(0xffff0000|decIMMD),decRX);
  1526.       else
  1527.         sprintf(insn_buf,"lwu\tr%d,0x%04x(r%d)\n",decRY,decIMMD,decRX);
  1528.       break;
  1529.     case 030:/* sb */
  1530.       if(decIMMD&0x8000)
  1531.         sprintf(insn_buf,"sb\tr%d,-0x%04x(r%d)\n",decRY,-(long)(0xffff0000|decIMMD),decRX);
  1532.       else
  1533.         sprintf(insn_buf,"sb\tr%d,0x%04x(r%d)\n",decRY,decIMMD,decRX);
  1534.       break;
  1535.     case 031:/* sh */
  1536.       if(decIMMD&0x8000)
  1537.         sprintf(insn_buf,"sh\tr%d,-0x%04x(r%d)\n",decRY,-(long)(0xffff0000|decIMMD),decRX);
  1538.       else
  1539.         sprintf(insn_buf,"sh\tr%d,0x%04x(r%d)\n",decRY,decIMMD,decRX);
  1540.       break;
  1541.     case 032:/* swsp */
  1542.       if(decIMMD&0x8000)
  1543.         sprintf(insn_buf,"sw\tr%d,-0x%04x(sp)\n",decRX,-(long)(0xffff0000|decIMMD));
  1544.       else
  1545.         sprintf(insn_buf,"sw\tr%d,0x%04x(sp)\n",decRX,decIMMD);
  1546.       break;
  1547.     case 033:/* sw */
  1548.       if(decIMMD&0x8000)
  1549.         sprintf(insn_buf,"sw\tr%d,-0x%04x(r%d)\n",decRY,-(long)(0xffff0000|decIMMD),decRX);
  1550.       else
  1551.         sprintf(insn_buf,"sw\tr%d,0x%04x(r%d)\n",decRY,decIMMD,decRX);
  1552.       break;
  1553.     case 034:/* RRR */
  1554.       sprintf(insn_buf,"reserved(RRR)\n");
  1555.       break;
  1556.     case 035:/* RR */
  1557.       dis_mips16_RR(decRR,decRX,decRY,decSA,insn);
  1558.       break;
  1559.     case 036:/* extend */
  1560.       sprintf(insn_buf,"reserved(EXTEND)\n");
  1561.       break;
  1562.     case 037:/* I64 */
  1563.       switch(decRX&7){
  1564.       case 0:
  1565.         if(decIMMD&0x8000)
  1566.           sprintf(insn_buf,"ld\tr%d,-0x%04x(sp)\n",decRY,-(long)(0xffff0000|decIMMD));
  1567.         else
  1568.           sprintf(insn_buf,"ld\tr%d,0x%04x(sp)\n",decRY,decIMMD);
  1569.         break;
  1570.       case 1:
  1571.         if(decIMMD&0x8000)
  1572.           sprintf(insn_buf,"sd\tr%d,-0x%04x(sp)\n",decRY,-(long)(0xffff0000|decIMMD));
  1573.         else
  1574.           sprintf(insn_buf,"sd\tr%d,0x%04x(sp)\n",decRY,decIMMD);
  1575.         break;
  1576.       case 2:
  1577.         if(decIMMD&0x8000)
  1578.           sprintf(insn_buf,"sd\tra,-0x%04x(sp)\n",-(long)(0xffff0000|decIMMD));
  1579.         else
  1580.           sprintf(insn_buf,"sd\tra,0x%04x(sp)\n",decIMMD);
  1581.         break;
  1582.       case 3:
  1583.         if(decIMMD&0x8000)
  1584.           sprintf(insn_buf,"daddiu\tsp,-0x%04x\n",-(long)(0xffff0000|decIMMD));
  1585.         else
  1586.           sprintf(insn_buf,"daddiu\tsp,0x%04x\n",decIMMD);
  1587.         break;
  1588.       case 4:
  1589.         if(decIMMD&0x8000)
  1590.           sprintf(insn_buf,"ld\tr%d,-0x%04x(pc)\n",decRY,-(long)(0xffff0000|decIMMD));
  1591.         else
  1592.           sprintf(insn_buf,"ld\tr%d,0x%04x(pc)\n",decRY,decIMMD);
  1593.         break;
  1594.       case 5:
  1595.         if(decIMMD&0x8000)
  1596.           sprintf(insn_buf,"daddiu\tr%d,-0x%04x\n",decRY,-(long)(0xffff0000|decIMMD));
  1597.         else
  1598.           sprintf(insn_buf,"daddiu\tr%d,0x%04x\n",decRY,decIMMD);
  1599.         break;
  1600.       case 6:
  1601.         if(decIMMD&0x8000)
  1602.           sprintf(insn_buf,"daddiu\tr%d,pc,-0x%04x\n",decRY,-(long)(0xffff0000|decIMMD));
  1603.         else
  1604.           sprintf(insn_buf,"daddiu\tr%d,pc,0x%04x\n",decRY,decIMMD);
  1605.         break;
  1606.       default:
  1607.         if(decIMMD&0x8000)
  1608.           sprintf(insn_buf,"daddiu\tr%d,sp,-0x%04x\n",decRY,-(long)(0xffff0000|decIMMD));
  1609.         else
  1610.           sprintf(insn_buf,"daddiu\tr%d,sp,0x%04x\n",decRY,decIMMD);
  1611.         break;
  1612.       }
  1613.       break;
  1614.     }
  1615. }
  1616.  
  1617. static void dis_mips16( ulong insn, ulong pc)
  1618. {
  1619.     ulong    decOP,decRX,decRY,decRZ,decSA,decFUNC,decRR,decIMMD,decIMMD5,decTARG,decCODE;
  1620.     ulong    temppc;
  1621.  
  1622.     decOP    =               (insn>>11)&0x1f;
  1623.     decRX    =mips16_reg_get((insn>> 8)&0x7);
  1624.     decRY    =mips16_reg_get((insn>> 5)&0x7);
  1625.     decRZ    =mips16_reg_get((insn>> 2)&0x7);
  1626.     decSA    =               (insn>> 2)&0x7;
  1627.     decFUNC    =                insn     &0x3;
  1628.     decRR    =                insn     &0x1f;
  1629.     decIMMD    =                insn     &0xff;
  1630.     decIMMD5=                insn     &0x1f;
  1631.     decTARG    =                insn     &0x7ff;
  1632.     decCODE    =               (insn>> 5)&0x1f;
  1633.  
  1634. /* printf("DIS_mips16\n"); */
  1635.  
  1636.     if(dis_extend_flag){
  1637.         dis_mips16_extend(insn,pc);
  1638.         dis_extend_flag = 0;
  1639.       }
  1640.     else{
  1641.  
  1642.     switch(decOP){
  1643.     case 000:/* addiusp */
  1644.       sprintf(insn_buf,"addiu\tr%d,sp,0x%03x\n",decRX,decIMMD<<2);
  1645.       break;
  1646.     case 001:/* addiupc */
  1647.       sprintf(insn_buf,"addiu\tr%d,pc,0x%03x\n",decRX,decIMMD<<2);
  1648.       break;
  1649.     case 002:/* b */
  1650.       if(decTARG&0x400)
  1651.         temppc=(0xfffff800|decTARG)<<1;
  1652.       else
  1653.         temppc=decTARG<<1;
  1654.       temppc+=2+pc;
  1655.       sprintf(insn_buf,"b\t0x%08x\n",temppc);
  1656.       break;
  1657.     case 003:/* jal(x) */
  1658.       sprintf(insn_buf,"jal(x)\n");
  1659.       dis_extend_flag=1;
  1660.       dis_extend_inst=insn;
  1661.       dis_jal_flag=1;
  1662.       break;
  1663.     case 004:/* beqz */
  1664.       if(decIMMD&0x80)
  1665.         temppc=(0xffffff00|decIMMD)<<1;
  1666.       else
  1667.         temppc=decIMMD<<1;
  1668.       temppc+=2+pc;
  1669.       sprintf(insn_buf,"beqz\tr%d,0x%08x\n",decRX,temppc);
  1670.       break;
  1671.     case 005:/* bnez */
  1672.       if(decIMMD&0x80)
  1673.         temppc=(0xffffff00|decIMMD)<<1;
  1674.       else
  1675.         temppc=decIMMD<<1;
  1676.       temppc+=2+pc;
  1677.       sprintf(insn_buf,"bnez\tr%d,0x%08x\n",decRX,temppc);
  1678.       break;
  1679.     case 006:/* SHIFT */
  1680.       if(decSA==0)
  1681.         decSA = 8;
  1682.       switch(decFUNC){
  1683.       case 0:/* sll  */
  1684.         sprintf(insn_buf,"sll\tr%d,r%d,%d\n",decRX,decRY,decSA);
  1685.         break;
  1686.       case 1:/* dsll */
  1687.         sprintf(insn_buf,"dsll\tr%d,r%d,%d\n",decRX,decRY,decSA);
  1688.         break;
  1689.       case 2:/* srl  */
  1690.         sprintf(insn_buf,"srl\tr%d,r%d,%d\n",decRX,decRY,decSA);
  1691.         break;
  1692.        default:/* sra */
  1693.         sprintf(insn_buf,"sra\tr%d,r%d,%d\n",decRX,decRY,decSA);
  1694.       }
  1695.       break;
  1696.     case 007:/* ld */
  1697.         sprintf(insn_buf,"ld\tr%d,0x%02x(r%d)\n",decRY,decIMMD5<<3,decRX);
  1698.         break;
  1699.     case 010:/* RRI-A */
  1700.       if(insn&0x10){/* daddiu */
  1701.         if(insn&0x8)
  1702.           sprintf(insn_buf,"daddiu\tr%d,r%d,-0x%x\n",decRY,decRX,-(long)(0xfffffff0|(insn&0xf)));
  1703.         else
  1704.           sprintf(insn_buf,"daddiu\tr%d,r%d,0x%x\n",decRY,decRX,(insn&0xf));
  1705.       }
  1706.       else{/* addiu */
  1707.         if(insn&0x8)
  1708.           sprintf(insn_buf,"addiu\tr%d,r%d,-0x%x\n",decRY,decRX,-(long)(0xfffffff0|(insn&0xf)));
  1709.         else
  1710.           sprintf(insn_buf,"addiu\tr%d,r%d,0x%x\n",decRY,decRX,(insn&0xf));
  1711.       }
  1712.       break;
  1713.     case 011:/* addiu8 */
  1714.       if(decIMMD&0x80)
  1715.         sprintf(insn_buf,"addiu\tr%d,-0x%02x\n",decRX,-(long)(0xffffff00|decIMMD));
  1716.       else
  1717.         sprintf(insn_buf,"addiu\tr%d,0x%02x\n",decRX,decIMMD);
  1718.       break;
  1719.     case 012:/* slti */
  1720.       sprintf(insn_buf,"slti\tr%d,0x%02x\n",decRX,decIMMD);
  1721.       break;
  1722.     case 013:/* sltiu */
  1723.       sprintf(insn_buf,"sltiu\tr%d,0x%02x\n",decRX,decIMMD);
  1724.       break;
  1725.     case 014:/* l8 */
  1726.       switch((insn>>8)&7){
  1727.       case 0:/* bteqz */
  1728.         if(decIMMD&0x80)
  1729.           temppc=(0xffffff00|decIMMD)<<1;
  1730.         else
  1731.           temppc=decIMMD<<1;
  1732.         temppc+=2+pc;
  1733.         sprintf(insn_buf,"bteqz\t0x%08x\n",temppc);
  1734.         break;
  1735.       case 1:/* btnez */
  1736.         if(decIMMD&0x80)
  1737.           temppc=(0xffffff00|decIMMD)<<1;
  1738.         else
  1739.           temppc=decIMMD<<1;
  1740.         temppc+=2+pc;
  1741.         sprintf(insn_buf,"btnez\t0x%08x\n",temppc);
  1742.         break;
  1743.       case 2:/* swrasp */
  1744.         sprintf(insn_buf,"sw\tra,0x%02x(sp)\n",decIMMD<<2);
  1745.         break;
  1746.       case 3:/* adjsp */
  1747.         if(decIMMD&0x80)
  1748.           sprintf(insn_buf,"addiu\tsp,-0x%03x\n",-(long)((0xffffff00|decIMMD)<<3));
  1749.         else
  1750.           sprintf(insn_buf,"addiu\tsp,0x%03x\n",decIMMD<<3);
  1751.         break;
  1752.       case 4:
  1753.         sprintf(insn_buf,"reserved(I8)\n");
  1754.         break;
  1755.       case 5:/* mov32r */
  1756.         sprintf(insn_buf,"move\tr%d,r%d\n",((decIMMD>>5)&7)|(decIMMD&0x18),
  1757.                     mips16_reg_get(decIMMD&0x7));
  1758.         break;
  1759.       case 6:
  1760.         sprintf(insn_buf,"reserved(I8)\n");
  1761.         break;
  1762.       default:/* movr32 */
  1763.         sprintf(insn_buf,"move\tr%d,r%d\n",decRY,decIMMD5);
  1764.       }
  1765.       break;
  1766.     case 015:/* li */
  1767.           sprintf(insn_buf,"li\tr%d,0x%02x\n",decRX,decIMMD);
  1768.       break;
  1769.     case 016:/* cmpi */
  1770.       sprintf(insn_buf,"cmpi\tr%d,0x%02x\n",decRX,decIMMD);
  1771.       break;
  1772.     case 017:/* sd */
  1773.       sprintf(insn_buf,"sd\tr%d,0x%02x(r%d)\n",decRY,decIMMD5<<3,decRX);
  1774.       break;
  1775.     case 020:/* lb */
  1776.       sprintf(insn_buf,"lb\tr%d,0x%02x(r%d)\n",decRY,decIMMD5,decRX);
  1777.       break;
  1778.     case 021:/* lh */
  1779.       sprintf(insn_buf,"lh\tr%d,0x%02x(r%d)\n",decRY,decIMMD5<<1,decRX);
  1780.       break;
  1781.     case 022:/* lwsp */
  1782.       sprintf(insn_buf,"lw\tr%d,0x%02x(sp)\n",decRX,decIMMD<<2);
  1783.       break;
  1784.     case 023:/* lw */
  1785.       sprintf(insn_buf,"lw\tr%d,0x%02x(r%d)\n",decRY,decIMMD5<<2,decRX);
  1786.       break;
  1787.     case 024:/* lbu */
  1788.       sprintf(insn_buf,"lbu\tr%d,0x%02x(r%d)\n",decRY,decIMMD5,decRX);
  1789.       break;
  1790.     case 025:/* lhu */
  1791.       sprintf(insn_buf,"lhu\tr%d,0x%02x(r%d)\n",decRY,decIMMD5<<1,decRX);
  1792.       break;
  1793.     case 026:/* lwpc */
  1794.       sprintf(insn_buf,"lw\tr%d,0x%02x(pc)\n",decRX,decIMMD<<2);
  1795.       break;
  1796.     case 027:/* lwu */
  1797.       sprintf(insn_buf,"lwu\tr%d,0x%02x(r%d)\n",decRY,decIMMD5<<2,decRX);
  1798.       break;
  1799.     case 030:/* sb */
  1800.       sprintf(insn_buf,"sb\tr%d,0x%02x(r%d)\n",decRY,decIMMD5,decRX);
  1801.       break;
  1802.     case 031:/* sh */
  1803.       sprintf(insn_buf,"sh\tr%d,0x%02x(r%d)\n",decRY,decIMMD5<<1,decRX);
  1804.       break;
  1805.     case 032:/* swsp */
  1806.       sprintf(insn_buf,"sw\tr%d,0x%02x(sp)\n",decRX,decIMMD<<2);
  1807.       break;
  1808.     case 033:/* sw */
  1809.       sprintf(insn_buf,"sw\tr%d,0x%02x(r%d)\n",decRY,decIMMD5<<2,decRX);
  1810.       break;
  1811.     case 034:/* RRR */
  1812.       switch(decFUNC){
  1813.       case 0:/* daddu */
  1814.         sprintf(insn_buf,"daddu\tr%d,r%d,r%d\n",decRZ,decRX,decRY);
  1815.         break;
  1816.       case 1:/* addu  */
  1817.         sprintf(insn_buf,"addu\tr%d,r%d,r%d\n",decRZ,decRX,decRY);
  1818.         break;
  1819.       case 2:/* dsubu */
  1820.         sprintf(insn_buf,"dsubu\tr%d,r%d,r%d\n",decRZ,decRX,decRY);
  1821.         break;
  1822.       default:/* subu */
  1823.         sprintf(insn_buf,"subu\tr%d,r%d,r%d\n",decRZ,decRX,decRY);
  1824.       }
  1825.       break;
  1826.     case 035:/* RR */
  1827.       dis_mips16_RR(decRR,decRX,decRY,decSA,insn);
  1828.       break;
  1829.     case 036:/* extend */
  1830.       dis_extend_flag = 1;
  1831.       dis_extend_inst = insn;
  1832.       sprintf(insn_buf,"extend\n");
  1833.       break;
  1834.     case 037:/* I64 */
  1835.       switch((insn>>8)&7){
  1836.       case 0:
  1837.         sprintf(insn_buf,"ld\tr%d,0x%02x(sp)\n",decRY,decIMMD5<<3);
  1838.         break;
  1839.       case 1:
  1840.         sprintf(insn_buf,"sd\tr%d,0x%02x(sp)\n",decRY,decIMMD5<<3);
  1841.         break;
  1842.       case 2:
  1843.         sprintf(insn_buf,"sd\tra,0x%03x(sp)\n",decIMMD<<3);
  1844.         break;
  1845.       case 3:
  1846.         if(decIMMD&0x80)
  1847.           sprintf(insn_buf,"daddiu\tsp,-0x%03x\n",-(long)((0xffffff00|decIMMD)<<3));
  1848.         else
  1849.           sprintf(insn_buf,"daddiu\tsp,0x%03x\n",decIMMD<<3);
  1850.         break;
  1851.       case 4:
  1852.         sprintf(insn_buf,"ld\tr%d,0x%02x(pc)\n",decRY,decIMMD5<<3);
  1853.         break;
  1854.       case 5:
  1855.         if(decIMMD5&0x10)
  1856.           sprintf(insn_buf,"daddiu\tr%d,-0x%x\n",decRY,-(long)(0xffffffe0|decIMMD5));
  1857.         else
  1858.           sprintf(insn_buf,"daddiu\tr%d,0x%x\n",decRY,decIMMD5);
  1859.         break;
  1860.       case 6:
  1861.         sprintf(insn_buf,"daddiu\tr%d,pc,0x%02x\n",decRY,decIMMD5<<2);
  1862.         break;
  1863.       default:
  1864.         sprintf(insn_buf,"daddiu\tr%d,sp,0x%02x\n",decRY,decIMMD5<<2);
  1865.       }
  1866.       break;
  1867.     }
  1868.       }
  1869.     printf("%08x %04x : %s",pc,opcode,insn_buf);
  1870. }
  1871.